/**
 *
 */
package persistence;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import domain.users.Member;
import domain.users.User;
import interfaces.UserRepository;

/**
 * @author doralt
 *
 */
public class XMLUserRepository implements UserRepository {

	/** **/
	private final File USER_FILE;
	/** **/
	private Map<Member, Integer> _userData;
	/** **/
	private XMLFileHandler _filerHandler;


	/**
	 *
	 * @throws IOException
	 */@SuppressWarnings("unchecked")
	public XMLUserRepository(String filename)throws IOException{
		this._filerHandler = new XMLFileHandler();
		this.USER_FILE = new File(filename);
		this._userData = (Map<Member, Integer>) this._filerHandler.loadDB(USER_FILE);
		if (this._userData == null){
			this._userData = new HashMap<Member, Integer>();
		}

	}

	/**
	 *
	 * @see interfaces.UserRepository#addUser(java.lang.String, java.lang.String)
	 */
	public boolean addUser(String username, String email, String password) {

		if(!isAvailableUsername(username)) return false;
		Member user = new Member(username,email);
		this._userData.put(user, password.hashCode()+user.getSalt());
		try {
			this._filerHandler.saveDB(this._userData, USER_FILE);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	private boolean isAvailableUsername(String username) {
		Set<Member> userSet = this._userData.keySet();
		for ( User user : userSet) {
			if (((Member)user).getUserName().equals(username)){
				return false;
			}
		}
		return true;
	}
	/**
	 *
	 * @see interfaces.UserRepository#changeRank(java.lang.String, int)
	 */
	public boolean changeRank(String username, int type) {
		Member tmember = (Member)this.getUser(username);
		if (tmember==null) return false;
		int rank = tmember.getRank();
		if ( (type+rank < 1)  || (type+rank > 3) ){
			return false;
		}
		tmember.setRank(rank+type);
		try {
			this._filerHandler.saveDB(this._userData, USER_FILE);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	/**
	 *
	 * @see interfaces.UserRepository#exists(java.lang.String, java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public boolean authenticate(String username, String password) {
		try {
			this._userData = (Map<Member, Integer>) this._filerHandler.loadDB(USER_FILE);
			if (this._userData == null){
				this._userData = new HashMap<Member, Integer>();
			}
			Set<Entry<Member, Integer>> tset =  (Set<Entry<Member, Integer>>) this._userData.entrySet();
			for (Entry<Member, Integer> entry : tset) {
				if (entry.getKey().getUserName().equals(username) &&
					entry.getValue().intValue() == password.hashCode()+entry.getKey().getSalt()){
					return true; // known registered user!!
				}
			}
		} catch (IOException e) {
			return false;
		}
		return false;
	}

	/**
	 *
	 * @see interfaces.UserRepository#getUser(java.lang.String)
	 */
	public User getUser(String username) {
		Set<Member> userSet = this._userData.keySet();
		for ( User user : userSet) {
			if (((Member)user).getUserName().equals(username)){
				return user;
			}
		}
		return null;
	}

	/**
	 *
	 * @see interfaces.UserRepository#removeUser(java.lang.String)
	 */
	public boolean removeUser(String username) {
		if (!exists(username)) return true;
		this._userData.remove(getUser(username));
		try {
			this._filerHandler.saveDB(this._userData, USER_FILE);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	public boolean exists(String username) {
		return !this.isAvailableUsername(username);
	}


	public boolean updateUser(String username, String newEmail, String oldPass, String newPass) {
		// TODO Auto-generated method stub
		return false;
	}

}
